clear all;

rand('seed', 3452);


global Q_LIMIT;
global BUSY;
global IDLE;

global next_event_type;
global num_custs_delayed;
global num_custs_delayed_more_than_a_minute;
global num_delays_required;
global num_events;
global num_in_q;
global server_status;

global area_num_in_q;
global area_server_status;
global max_q_length;
global max_time_in_q;
global total_time_in_system;
global max_time_in_system;
global mean_interarrival;
global mean_service;
global time;
global time_arrival;
global time_last_event;
global time_next_event;
global total_of_delays;

%
Q_LIMIT = 10000;
BUSY    = 1;
IDLE    = 0;

% Abre los archivos I/O
inpfile = fopen('mm1.inp','r');
outfile = fopen('mm1.out','w');

% Especifica el numero de eventos
num_events = 2;

% Lee el archivo de entrada
xdata = fscanf(inpfile,'%f %f %f',[1 3]);
mean_interarrival   = xdata(1);
mean_service        = xdata(2);
num_delays_required = xdata(3);
 

% Escribe los encabezados de los reportes y parametros de entrada
fprintf(outfile,'Sistema de cola de servidor simple\n\n');
fprintf(outfile,'Tiempo medio entre arribos %11.3f minutos\n\n',mean_interarrival);
fprintf(outfile,'Tiempo medio de servicio   %11.3f minutos\n\n',mean_service);
fprintf(outfile,'Numero de clientes         %14d\n\n', num_delays_required);

ro = 0.05:0.02:0.95;
lambda = ro * (1/mean_service);

estimatedW = zeros(1, length(lambda));
realW = 1 ./ ((1/mean_service) - lambda);

for i=1:length(lambda)
    mean_interarrival = 1/lambda(i);
    
    relError = abs(estimatedW(i)-realW(i)) / realW(i);
    
    numTimes = 1;
    acumW = 0;
    while relError > 0.05
        % Inicializa la simulacion
        initialize();
        % Corre la simulacion
        while num_custs_delayed < num_delays_required && relError > 0.05
            % Determina el proximo evento
            timing();

            % Actualiza los acumuladores estadisticos de tiempos medios
            update_time_avg_stats();

            % Invoca al evento apropiado
            switch (next_event_type)
                case 1
                    arrive();
                    %break;
                case 2
                    depart();
                    %break;
            end
            estimatedW(i) = (acumW + total_time_in_system / num_custs_delayed) / numTimes; 
            relError = abs(estimatedW(i)-realW(i)) / realW(i);
        end
        acumW = acumW + total_time_in_system / num_custs_delayed;
        numTimes = numTimes + 1;
    end
end

plot(0.05:0.02:0.95, estimatedW, '.', 0.05:0.02:0.95, realW);

% Invoca al generador de reportes y fin de la simulacion
%report(outfile);
fclose(inpfile);
fclose(outfile);